package com.myersinfosys.protrack.poi;

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

//import java.awt.Color;
import java.io.FileOutputStream;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;

public class ExcelCalendar
{
    private static final String[] days = {
        "Sunday", "Monday", "Tuesday",
        "Wednesday", "Thursday", "Friday", "Saturday"};

    private static final String[]  months = {
        "January", "February", "March","April", "May", "June","July", "August",
        "September","October", "November", "December"};
    
   private Calendar calendar;
   private Workbook wb;
   private Boolean isXlsx;
   private Map<String, CellStyle> styles;
   private String filename;

   public ExcelCalendar(String filename) {
	   
	   this.calendar = Calendar.getInstance();
	   
	   this.isXlsx = filename.matches("(?i).*.xlsx");
	   this.wb = isXlsx ? new XSSFWorkbook() : new HSSFWorkbook();
	   this.filename = filename;
	   
	   this.styles = createStyles(this.wb);
   }

   public int createExcelCalendar(int startYear, int startMonth, int nMonths, int startDay, int startDow)
   {
	   int year;
	   int month;
	   final Calendar today = Calendar.getInstance();
	   int success = 0;
	   
       if (startYear < 0) 
    	   startYear = calendar.get(Calendar.YEAR);
       
       if (startMonth < 0 || startMonth > 11)
    	   startMonth = calendar.get(Calendar.MONTH);
       
       if (nMonths < 1 || nMonths > 12)
    	   nMonths = 12;
       
       if(startDay < 0 || startDay > 26)
    	   startDay = 1;
       
       if(startDow <0 || startDow > 6)
    	   startDow = calendar.getFirstDayOfWeek();
       
       year = startYear;
       month = startMonth-1;
       
       for (int monthIndex = 0; monthIndex < nMonths; monthIndex++) {
    	   month++;
    	   if(month > 11) {
    		   year++;
    		   month = 0;
    	   } 
    	   calendar.set(Calendar.YEAR, year);
           calendar.set(Calendar.MONTH, month);
           calendar.set(Calendar.DAY_OF_MONTH, startDay);
           calendar.setFirstDayOfWeek(startDow);
           //create a sheet for each month
           Sheet sheet = wb.createSheet(months[month]+" "+year);

           //turn off gridlines
           sheet.setDisplayGridlines(false);
           sheet.setPrintGridlines(false);
           sheet.setFitToPage(true);
           sheet.setHorizontallyCenter(true);
           PrintSetup printSetup = sheet.getPrintSetup();
           printSetup.setLandscape(true);

           //the following three statements are required only for HSSF
           sheet.setAutobreaks(true);
           printSetup.setFitHeight((short)1);
           printSetup.setFitWidth((short)1);

           //the header row: centered text in 48pt font
           Row headerRow = sheet.createRow(0);
           headerRow.setHeightInPoints(80);
           Cell titleCell = headerRow.createCell(0);
           titleCell.setCellValue(months[month] + " " + year);
           titleCell.setCellStyle(styles.get("title"));
           sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$N$1"));

           //header with month titles
           Row monthRow = sheet.createRow(1);
           for (int i = 0; i < days.length; i++) {
               //set column widths, the width is measured in units of 1/256th of a character width
               sheet.setColumnWidth(i*2, 5*256); //the column is 5 characters wide
               sheet.setColumnWidth(i*2 + 1, 13*256); //the column is 13 characters wide
               sheet.addMergedRegion(new CellRangeAddress(1, 1, i*2, i*2+1));
               Cell monthCell = monthRow.createCell(i*2);
               int dowIndex = startDow + i;
               if (dowIndex >= days.length)
            	   dowIndex -= days.length; 
               monthCell.setCellValue(days[dowIndex]);
               monthCell.setCellStyle(styles.get("month"));
           }

           int cnt = 1, day=1;
           int rownum = 2;
           for (int j = 0; j < 6; j++) {
               Row row = sheet.createRow(rownum++);
               row.setHeightInPoints(100);
               for (int i = 0; i < days.length; i++) {
                   Cell dayCell_1 = row.createCell(i*2);
                   Cell dayCell_2 = row.createCell(i*2 + 1);

                   int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - startDow;
                   
                   if(cnt >= day_of_week && calendar.get(Calendar.MONTH) == month) {
                       dayCell_1.setCellValue(day);
                       Boolean isToday = (today.get(Calendar.YEAR)==year &&
                    		  today.get(Calendar.DAY_OF_YEAR)==calendar.get(Calendar.DAY_OF_YEAR));
                    		  
                       calendar.set(Calendar.DAY_OF_MONTH, ++day);

                       if(day_of_week == 0 || day_of_week == 6) {
                    	   
                    	   dayCell_1.setCellStyle(styles.get((isToday) ? "today_weekend_left" : "weekend_left"));
                           dayCell_2.setCellStyle(styles.get("weekend_right"));
                       } else {
                    	   
                           dayCell_1.setCellStyle(styles.get((isToday) ? "today_workday_left" : "workday_left"));
                           dayCell_2.setCellStyle(styles.get("workday_right"));
                       }
                   } else {
                       dayCell_1.setCellStyle(styles.get("grey_left"));
                       dayCell_2.setCellStyle(styles.get("grey_right"));
                   }
                   cnt++;
               }
               if(calendar.get(Calendar.YEAR) > year && calendar.get(Calendar.MONTH) > month) 
            	   break;
           }
       }

       // Write the output to a file
	try {
		FileOutputStream out = new FileOutputStream(filename);
	     wb.write(out);
	     out.close();
	     success = 1;
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		success= 0;
	}
  
	return success;
   }

   /**
    * cell styles used for formatting calendar sheets
    */
   private static Map<String, CellStyle> createStyles(Workbook wb){
       Map<String, CellStyle> styles = new HashMap<String, CellStyle>();

       short borderColor = IndexedColors.GREY_50_PERCENT.getIndex();
       short lightBorderColor = IndexedColors.GREY_25_PERCENT.getIndex();
       short monthColor = IndexedColors.DARK_BLUE.getIndex();
       short whiteColor = IndexedColors.WHITE.getIndex();
       short blackColor = IndexedColors.BLACK.getIndex();
       short weekendColor;
       
       
       weekendColor = IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex();
       //short weekendColor = Color.BLUE.;
       //weekendColor = (new XSSFColor(new java.awt.Color(255, 255, 128)))..getIndexed();
       
       final short def = -1;
       
       PoiExcelCellStyles cellStyles = new PoiExcelCellStyles(wb);
       
       // create the fonts
       Font titleFont = cellStyles.createCustomFontStyle(null, 
    		   (short)48, 
    		   monthColor, 
				false, 
				false,
				false);
       Font monthFont = cellStyles.createCustomFontStyle(null, 
    		   (short)12, 
    		   whiteColor, 
				true, 
				false,
				false);
       Font dayFont = cellStyles.createCustomFontStyle(null, 
    		   (short)14, 
    		   blackColor, 
				true, 
				false,
				false);
       Font todayFont = cellStyles.createCustomFontStyle(null, 
    		   (short)16, 
    		   monthColor, 
				true, 
				false,
				true);       
       
       
       CellStyle style = cellStyles.createCustomCellStyle(titleFont, 
			   def,def,def,def,
			   def,def,def,def,
			   def,
			   def,
			   def,
			   CellStyle.ALIGN_CENTER,
			   CellStyle.VERTICAL_CENTER,
			   false);
       styles.put("title", style);
       
       

       style = cellStyles.createCustomCellStyle(monthFont, 
			   def,def,def,def,
			   def,def,def,def,
			   def,
			   monthColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_CENTER,
			   CellStyle.VERTICAL_CENTER,
			   false);       
       styles.put("month", style);

       
       style = cellStyles.createCustomCellStyle(dayFont, 
    		   def,def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,
			   def,def,borderColor,borderColor,
			   def,
			   weekendColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_LEFT,
			   CellStyle.VERTICAL_TOP,
			   false);              
       styles.put("weekend_left", style);
       
       style = cellStyles.createCustomCellStyle(todayFont, 
    		   def,def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,
			   def,def,borderColor,borderColor,
			   def,
			   weekendColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_LEFT,
			   CellStyle.VERTICAL_TOP,
			   false);              
       styles.put("today_weekend_left", style);       
       

       style = cellStyles.createCustomCellStyle(dayFont, 
    		   def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,def,
			   def,borderColor,borderColor,def,
			   def,
			   weekendColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_CENTER,
			   CellStyle.VERTICAL_TOP,
			   false);                     
       styles.put("weekend_right", style);

       
       style = cellStyles.createCustomCellStyle(dayFont, 
    		   def,def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,
			   def,def,borderColor,borderColor,
			   def,
			   whiteColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_LEFT,
			   CellStyle.VERTICAL_TOP,
			   false);       
       styles.put("workday_left", style);
       
       style = cellStyles.createCustomCellStyle(todayFont, 
    		   def,def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,
			   def,def,borderColor,borderColor,
			   def,
			   whiteColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_LEFT,
			   CellStyle.VERTICAL_TOP,
			   false);       
       styles.put("today_workday_left", style);       

       
       style = cellStyles.createCustomCellStyle(dayFont, 
    		   def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,def,
			   def,borderColor,borderColor,def,
			   def,
			   whiteColor,
			   CellStyle.SOLID_FOREGROUND,
			   CellStyle.ALIGN_CENTER,
			   CellStyle.VERTICAL_TOP,
			   false);       
       styles.put("workday_right", style);


       style = cellStyles.createCustomCellStyle(dayFont, 
    		   def,def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,
			   def,def,borderColor,def,
			   def,
			   lightBorderColor,
			   CellStyle.SOLID_FOREGROUND,
			   def,
			   def,
			   false);       
       styles.put("grey_left", style);


       style = cellStyles.createCustomCellStyle(dayFont, 
    		   def,CellStyle.BORDER_THIN,CellStyle.BORDER_THIN,def,
			   def,borderColor,borderColor,def,
			   def,
			   lightBorderColor,
			   CellStyle.SOLID_FOREGROUND,
			   def,
			   def,
			   false);       
       styles.put("grey_right", style);

       return styles;
   }
 }